﻿#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

//int main()
//{
//	int num = 10;//int = signed int 
//
//	return 0;
//}

/*
num = 10
	00000000000000000000000000001010  10的源码
	正数的源码、反码、补码是一样的
*/

/*
num = -10
	10000000000000000000000000001010  -10的源码
	11111111111111111111111111110101  -10的反码
	11111111111111111111111111110110  -10的补码

	11111111111111111111111111110110  -10的补码
	10000000000000000000000000001001
	10000000000000000000000000001010  -10的源码 
*/

/*
	1 + -1
	1 + （-1）
	00000000000000000000000000000001  1的源码
	10000000000000000000000000000001  -1的源码
	10000000000000000000000000000010  ❌

	数据的计算在内存中是以二进制补码的形式进行的
	cpu只有加法器

	10000000000000000000000000000001  -1的源码
	11111111111111111111111111111110  -1的反码
	11111111111111111111111111111111  -1的补码

	00000000000000000000000000000001  1的补码
	11111111111111111111111111111111  -1的补码
	00000000000000000000000000000000  1 + （-1）的补码

*/

//int main()
//{
//	int num = 10;
//	int r = num << 1;
//	printf("%d\n", num);// 10
//	printf("%d\n", r);// 20
//
//	return 0;
//}

/*
	00000000000000000000000000001010  10的源码、反码、补码

	num << 1
	00000000000000000000000000010100  补码 --->源码
	正数的源码、反码、补码是一样的
*/

//int main()
//{
//	int num = -10;
//	int r = num << 1;
//	printf("%d\n", num);// -10
//	printf("%d\n", r);// -20
//
//	return 0;
//}

/*
	10000000000000000000000000001010  -10的源码
	11111111111111111111111111110101  -10的反码
	11111111111111111111111111110110  -10的补码

	num << 1
	11111111111111111111111111101100  r 的补码
	10000000000000000000000000010011  r 的反码
	10000000000000000000000000010100  r 的源码

*/

//int main()
//{
//	int num = 10;
//	int r = num >> 1;
//	printf("%d\n", num);// 10
//	printf("%d\n", r);// 5
//
//	return 0;
//}

/*
	num:
	00000000000000000000000000001010   num = 10的补码

	num >> 1:
	00000000000000000000000000000101   r  的补码
	00000000000000000000000000000101   r  的源码

*/

//int main()
//{
//	int num = -10;
//	int r = num >> 1;
//	printf("%d\n", num);// -10
//	printf("%d\n", r);// -5
//
//	return 0;
//}

/*
	num:
	10000000000000000000000000001010   10的源码
	11111111111111111111111111110101   10的反码
	11111111111111111111111111110110   10的补码

	num >> 1:
	11111111111111111111111111111011   r的补码
	10000000000000000000000000000100   r的反码
	10000000000000000000000000000101   r的源码

*/

/*
	右移操作符 ---> 逻辑右移  算术右移
	由编译器决定是逻辑右移还是算术右移
	目前，大多数编译器都是算术右移
*/

//int main()
//{
//	int a = 3;
//	int b = -6;
//	int r = a & b;
//	printf("%d\n", r);// 2
//	return 0;
//}

/*
	00000000000000000000000000000011   3的补码

	10000000000000000000000000000110   -6的源码
	11111111111111111111111111111001   -6的反码
	11111111111111111111111111111010   -6的补码

	00000000000000000000000000000011   3的补码
	11111111111111111111111111111010   -6的补码
	00000000000000000000000000000010   r的补码 --> 源码


*/

//int main()
//{
//	int a = 3;
//	int b = -6;
//	int r = a | b;
//	printf("%d\n", r);// -5
//	return 0;
//}

/*
	00000000000000000000000000000011   3的补码

	10000000000000000000000000000110   -6的源码
	11111111111111111111111111111001   -6的反码
	11111111111111111111111111111010   -6的补码

	00000000000000000000000000000011   3的补码
	11111111111111111111111111111010   -6的补码
	11111111111111111111111111111011   r 的补码
	10000000000000000000000000000100   
	10000000000000000000000000000101   r 的源码
*/


//int main()
//{
//	int a = 3;
//	int b = -6;
//	int r = a ^ b;
//	printf("%d\n", r);// -7
//	return 0;
//}

/*
	00000000000000000000000000000011   3的补码

	10000000000000000000000000000110   -6的源码
	11111111111111111111111111111001   -6的反码
	11111111111111111111111111111010   -6的补码

	00000000000000000000000000000011   3的补码
	11111111111111111111111111111010   -6的补码
	11111111111111111111111111111001   r 的补码
	10000000000000000000000000000110
	10000000000000000000000000000111   r 的源码
*/


//int main()
//{
//	int b = -6;
//	int r = ~b;
//	printf("%d\n", r);// 5
//	return 0;
//}

/*
	
	10000000000000000000000000000110   -6的源码
	11111111111111111111111111111001   -6的反码
	11111111111111111111111111111010   -6的补码
	
	11111111111111111111111111111010   -6的补码
	00000000000000000000000000000101   r 的补码 --> 源码
	
	
*/

/*
	不能创建临时变量（第三个变量），实现两个整数的交换。
*/

//int main()
//{
//	int a = 5;
//	int b = 3;
//	printf("交换前：a = %d  b = %d\n\n", a, b);
//	int c = a; // 违规使用第三个变量
//	a = b;
//	b = c;
//	printf("交换后：a = %d  b = %d\n\n", a, b);
//	return 0;
//}

//int main()
//{
//	int a = 5;
//	int b = 3;
//	printf("交换前：a = %d  b = %d\n\n", a, b);
//	a = a + b;
//	b = a - b;
//	a = a - b;
//	/*
//		当a、b数据很大时，计算时可能会导致数据溢出
//	*/
//	printf("交换后：a = %d  b = %d\n\n", a, b);
//	return 0;
//}

//int main()
//{
//	int a = 5;
//	int b = 3;
//	printf("交换前：a = %d  b = %d\n\n", a, b);
//	a = a ^ b;
//	b = a ^ b;
//	a = a ^ b;
//	printf("交换后：a = %d  b = %d\n\n", a, b);
//	return 0;
//}

/*
	原理：   异或是支持交换律的
	00000000000000000000000000000101   a = 5 的补码

	a ^ 0 = a
	00000000000000000000000000000101   a = 5 的补码
	00000000000000000000000000000000   0 的补码
	00000000000000000000000000000101   a ^ 0

	a ^ a = 0
	00000000000000000000000000000101   a = 5 的补码
	00000000000000000000000000000101   a = 5 的补码
	00000000000000000000000000000000   a ^ a 的补码

	a = a ^ b;  
	b = a ^ b;		b = a ^ b ^ b = a
	a = a ^ b;		a = a ^ b ^ a = b
*/

/*
	找出单身狗：
*/
// 一、 暴力去数
//int main()
//{
//	int arr[11] = { 5,0,4,11,89,6,6,0,4,89,5 };
//	int i = 0;
//	for (i = 0; i < 11; i++)
//	{
//		int j = 0;
//		for (j = i + 1; j < 11; j++)
//		{
//			if (arr[i] == arr[j])
//			{
//				printf("arr[%d] = %d 不是单身狗\n", i, arr[i]);
//				printf("arr[%d] = %d 不是单身狗\n", j, arr[j]);
//			}
//				
//		}
//	}
//
//	return 0;
//}

// 二、异或

//int main()
//{
//	int arr[11] = { 5,0,4,11,89,6,6,0,4,89,5 };
//	int i = 0;
//	int r = 0;
//	for (i = 0; i < 11; i++)
//	{
//		r ^= arr[i];
//	}
//	printf("这个单身狗是%d\n", r);
//
//	return 0;
//}


/*
	编写代码实现：
	求⼀个整数存储在内存中的⼆进制中1的个数。  (补码)
*/

//int main()
//{
//	int  n = 0;
//	scanf("%d", &n);
//	int count = 0;
//	while (n)
//	{
//		if (n % 2 == 1)
//		{
//			count++;
//		}
//		n /= 2;
//	}
//	printf("%d\n", count);
//
//	return 0;
//}


//int main()
//{
//	int  n = 0;
//	scanf("%d", &n);
//	int count = 0;
//	int i = 32;
//	while (i)
//	{
//		if ((n & 1) == 1)
//		{
//			count++;
//		}
//		n >>= 1;
//		i--;
//	}
//	
//	printf("%d\n", count);
//
//	return 0;
//}

/*
	10000000000000000000000000000001  -1的源码
	11111111111111111111111111111110  -1的反码
	11111111111111111111111111111111  -1的补码

	11111111111111111111111111111111  -1的补码
	00000000000000000000000000000001  1的补码

*/

//int main()
//{
//	int num = 0;
//	scanf("%d", &num);
//	int i = 0;
//	int count = 0;//计数
//	for (i = 0; i < 32; i++)
//	{
//		if (((num >> i) & 1) == 1)
//			count++;
//	}
//	printf("count = %d\n", count);
//	return 0;
//}

//int main()
//{
//	int num = 0;
//	scanf("%d", &num);
//	int i = 0;
//	int count = 0;//计数
//
//	while (num)
//	{
//		num = num & (num - 1);
//		count++;
//	}
//	
//	printf("count = %d\n", count);
//	return 0;
//}


//int main()
//{
//	int num = 0;
//	scanf("%d", &num);
//	if ((num & (num - 1)) == 0)
//	{
//		printf("num = %d 是2的次方数\n", num);
//	}
//	else
//	{
//		printf("num = %d 不是2的次方数\n", num);
//	}
//
//	return 0;
//}

/*
	⼆进制位置0或者置1
	编写代码将13⼆进制序列的第5位修改为1，然后再改回0
*/

//int main()
//{
//	int num = 13;
//	int n = 0;
//	scanf("%d", &n);
//	int r = num | (1 << (n - 1));
//	printf("r = %d\n", r);// 29
//
//	return 0;
//}

/*
	00000000000000000000000000001101   13的源码
	00000000000000000000000000011101   

*/

//int main()
//{
//	int num = 13;
//	int n = 0;
//	scanf("%d", &n);
//	int r = num | (1 << (n - 1));
//	printf("r = %d\n", r);// 29
//
//	r = r ^ (1 << (n - 1));
//	printf("r = %d\n", r);// 13
//
//	return 0;
//}

/*
	00000000000000000000000000001101   13的源码
	00000000000000000000000000011101

	00000000000000000000000000011101
	00000000000000000000000000010000
	00000000000000000000000000001101

	00000000000000000000000000011101   29的源码
	11111111111111111111111111101111
	00000000000000000000000000001101
*/

//int main()
//{
//	int num = 13;
//	int n = 0;
//	scanf("%d", &n);
//	int r = num | (1 << (n - 1));
//	printf("r = %d\n", r);// 29
//
//	r  &= ~(1 << (n - 1));
//	printf("r = %d\n", r);// 13
//
//	return 0;
//}

//int main()
//{
//	//sizeof的括号中有表达式的时候，是不参与计算的
//	short s = 10;
//	int n = 8;
//	printf("%zd\n", sizeof(s = n+9));// 2
//	printf("s = %d\n", s);// s = 10
//
//	return 0;
//}

//int main()
//{
//	int a = 1;
//	int b = 2;
//	int c = (a > b, a = b + 10, a, b = a + 1);
//	printf("c = %d\n", c);// c = 13
//
//	return 0;
//}


//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	//              0 1 2 3 4 5 ...
//	arr[5];//[] - 下标引用操作符
//	//arr 5是[]的操作数
//	//
//	return 0;
//}

//int Add(int x, int y)
//{
//	return x + y;
//}
//
//void test()
//{
//
//}
//
//int main()
//{
//	test();
//	printf("hehe\n");  //() 是函数调用操作符,printf, "hehe\n" 是两个操作数
//	Add(3, 5); //Add 3 5 是三个操作数
//	return 0;
//}

/*
	结构体
*/
//#include <stdio.h>
//struct std
//{
//	char name[20];
//	int age;
//	double score;
//}s1,s2;  //全局变量
//
//struct std s3;// 全局变量
//
//int main()
//{
//	struct std s4 = { "李四",20,65.5 };  // 局部变量 
//	struct std s5 = { "张三",18,99.8 };
//	//s1.name = "李四";    err
//	//s1.name[20] = "李四";   err
//	struct std s1 = { "王五",22,85.4 };
//	struct std s2 = { "麻子",22,85.4 };
//
//	printf("%s  %d  %lf\n", s1.name, s1.age, s1.score);
//	printf("%s  %d  %lf\n", s2.name, s2.age, s2.score);
//	printf("%s  %d  %lf\n", s4.name, s4.age, s4.score);
//	printf("%s  %d  %lf\n", s5.name, s5.age, s5.score);
//	return 0;
//}


//#include <stdio.h>
//struct Id
//{
//	int x;
//	int b;
//};
//
//struct std
//{
//	char name[20];
//	struct Id id;
//	int age;
//	double score;
//}s1, s2;  //全局变量
//
//struct std s3;// 全局变量
//
//int main()
//{
//	struct std s4 = { "李四",{001,20240001},20,65.5 };  // 局部变量 
//	struct std s5 = { "张三",{002,20240002},18,99.8 };
//	//s1.name = "李四";    err
//	//s1.name[20] = "李四";   err
//	struct std s1 = { "王五",{003,20240003},22,85.4 };
//	struct std s2 = { "麻子",{004,20240004},22,85.4 };
//
//
//	printf("%s  %d  %d  %d  %.2lf\n", s1.name, s1.id.x, s1.id.b, s1.age, s1.score);
//	printf("%s  %d  %d  %d  %.2lf\n", s2.name, s2.id.x, s2.id.b, s2.age, s2.score);
//	printf("%s  %d  %d  %d  %.2lf\n", s4.name, s4.id.x, s4.id.b, s4.age, s4.score);
//	printf("%s  %d  %d  %d  %.2lf\n", s5.name, s5.id.x, s5.id.b, s5.age, s5.score);
//	return 0;
//}


struct Id
{
	int x;
	char id[25];
};

struct Stu
{
	//成员列表
	char name[20];
	int age;
	struct Id id;
	double score;
}s4, s5;//全局变量

//int double 

//全局变量
struct Stu s3;

int main()
{
	//int num;
	//结构体变量 - 局部变量
	struct Stu s1 = { "zhangsan", 20, {1, "2025010102"}, 60.0 };
	//struct Stu s2 = {"lisi", 25, 85.5};
	struct Stu s2 = { .age = 25, .name = "lisi", .score = 85.5,.id.id = "2025010203", .id.x = 2 };
	printf("%s %d %d %s %lf\n", s1.name, s1.age, s1.id.x, s1.id.id, s1.score);
	s1.age = 25;
	printf("%s %d %d %s %lf\n", s1.name, s1.age, s1.id.x, s1.id.id, s1.score);

	//. 操作符 （结构成员访问操作符）
	//结构体变量.成员名
	//
	return 0;
}